package game.square;

import static org.junit.Assert.*;


import game.dungeon.position.Direction;
import org.junit.Before;
import org.junit.Test;

public class BorderTest {

	private Border createdBorder, terminatedBorder;
	
	@Before
	public void setUp(){
		createdBorder = new Wall(true);
		terminatedBorder = new Wall(true);
		terminatedBorder.terminate();
	}
	
	
	@Test
	public void terminateBorderWithTwoSquares_LegalCase(){
		CommonSquare square1 = new CommonSquare();
		CommonSquare square2 = new CommonSquare();
		// This is based on the default specification of the default constructor
		square1.addNeighborInDirection(square2, Direction.NORTH);
		Border border = square1.getBorderInDirection(Direction.NORTH);
		square1.removeBorderInDirection(Direction.NORTH);
		square2.removeBorderInDirection(Direction.SOUTH);
		border.terminate();
		assertTrue(border.isTerminated());
		assertTrue(border.getBorderedSquares()[1] == null
				&& border.getBorderedSquares()[2] == null);
		assertTrue(square1.getBorderInDirection(Direction.NORTH) == null);
		assertTrue(square2.getBorderInDirection(Direction.SOUTH) == null);
	}
	
	@Test
	public void terminateBorderWithOneSquare_LegalCase(){
		CommonSquare square = new CommonSquare();
		Border border = square.getBorderInDirection(Direction.NORTH);
		square.removeBorderInDirection(Direction.NORTH);
		border.terminate();
		assertTrue(border.isTerminated());
		assertTrue(border.getBorderedSquares()[1] == null
				&& border.getBorderedSquares()[2] == null);
		assertTrue(square.getBorderInDirection(Direction.NORTH) == null);
	}
	
	@Test
	public void terminateBorderWithoutSquares_LegalCase(){
		createdBorder.terminate();
		assertTrue(createdBorder.isTerminated());
		assertTrue(createdBorder.getBorderedSquares()[1] == null
				&& createdBorder.getBorderedSquares()[2] == null);
	}
	
	@Test (expected = AssertionError.class)
	public void terminateBorder_IllegalCase(){
		CommonSquare square = new CommonSquare();
		Border border = square.getBorderInDirection(Direction.NORTH);
		border.terminate();
	}
	@Test 
	public void terminateBorderAlreadyTerminated(){
		terminatedBorder.terminate();
		assertTrue(terminatedBorder.isTerminated());
		assertTrue(terminatedBorder.getBorderedSquares()[1] == null
				&& terminatedBorder.getBorderedSquares()[2] == null);
	}
	
	@Test
	public void canHaveAsSquare_LegalCase(){
		assertTrue(createdBorder.canHaveAsSquare(new CommonSquare()));
		Border placedBorder = new CommonSquare().getBorderInDirection(Direction.NORTH);
		assertTrue(placedBorder.canHaveAsSquare(new CommonSquare()));	
		assertTrue(placedBorder.canHaveAsSquare(null));
	}
	
	@Test 
	public void canHaveAsSquare_IllegalCaseTerminatedBorder(){
		assertFalse(terminatedBorder.canHaveAsSquare(new CommonSquare()));
	}
	
	@Test
	public void canHaveAsSquare_IllegalCaseTerminatedSquare(){
		CommonSquare square = new CommonSquare();
		Border border = square.getBorderInDirection(Direction.NORTH);
		square.removeBorderInDirection(Direction.NORTH);
		square.terminate();
		assertFalse(border.canHaveAsSquare(square));
	}
	
	@Test
	public void isBorderOf_SingleCase(){
		CommonSquare square = new CommonSquare();
		Border border = square.getBorderInDirection(Direction.NORTH);
		assertTrue(border.isBorderOf(square));
		assertFalse(border.isBorderOf(new CommonSquare()));
	}
	
	@Test
	public void getNeighborSquareFrom_LegalCase(){
		CommonSquare square1 = new CommonSquare();
		CommonSquare square2 = new CommonSquare();
		// This is based on the default specification of the default constructor
		square1.addNeighborInDirection(square2, Direction.NORTH);
		Border border = square1.getBorderInDirection(Direction.NORTH);
		assertEquals(border.getNeighborSquareFrom(square1),square2);
		assertEquals(border.getNeighborSquareFrom(square2),square1);
	}
	
	@Test (expected = AssertionError.class)
	public void getNeighborSquareFrom_IllegalCaseNoBorderOfSquare(){
		createdBorder.getNeighborSquareFrom(new CommonSquare());
	}
	
	@Test
	public void isStrongerThan_SingleCase(){
		Border wall = new Wall(true);
		Border noPhysicalBorder = new NoPhysicalBorder();
		Border door = new Door();
		assertTrue(wall.isStrongerThan(door));
		assertTrue(wall.isStrongerThan(noPhysicalBorder));
		assertTrue(door.isStrongerThan(noPhysicalBorder));
		assertFalse(noPhysicalBorder.isStrongerThan(wall));
		assertFalse(noPhysicalBorder.isStrongerThan(door));
		assertFalse(door.isStrongerThan(wall));
	}
	
	
}
